
#include "HeaderFiles.h"
#include "math.h"

#include "uart_comm_struct.h"
#include "uart_comm_ex_api.h"
#include "serialHMI_analysis.h"
#include "signal_handle.h"
#include "IO_check_handle.h"
#include "gpio_ctrl.h"
#include "turn_LED.h"
#include "color_LED.h"
#include "buzzer_ctrl.h"
#include "offline_param.h"

#include "power_ctrl.h"
#include "system_param.h"
#include "fault_analyse.h"

#include "robot_interact.h"

uint16_t systick_timestamp_1ms_flg = 0;
uint64_t systick_timecnt_1ms = 0;
static uint16_t counterLED[2] = {0, 0};

STR_USERHDL  userHdl;

STR_RINGBUF *KS104_REC_Buff = &UART1Recbuf;
STR_RINGBUF *KS104_TAR_Buff = &UART1Sendbuf;

STR_RINGBUF *TOF050_REC_Buff = &UART2Recbuf;
STR_RINGBUF *TOF050_TRA_Buff = &UART2Sendbuf;

uint16_t debug_arryX1 = 0;
uint16_t debug_arryX2 = 0;


uint16_t task_runtime_ms = 0;


void hmi_serialMini_handle(void);

/*!
    \brief      system_init
    \param[in]  none
    \param[out] none
    \retval     none
*/	
	
void system_init(void)
{
	systick_config();

	rcu_ahb_clock_config(RCU_AHB_CKSYS_DIV1);
	rcu_apb2_clock_config(RCU_APB2_CKAHB_DIV1);
	
	rcu_periph_clock_enable(RCU_AF);
	rcu_periph_clock_enable(RCU_GPIOA);
	rcu_periph_clock_enable(RCU_GPIOB);
	
	hardware_version_gpio_init();
	
	userHdl.param.software_version_num = SOFTWARE_VERSION_NUM;
	userHdl.param.hardware_version_num = get_hardware_version_num();
	
	heartbeat_led_init(userHdl.param.hardware_version_num);
	
	usart0_init();
	
	usart1_init();
	
	usart2_init();
	
	usart3_init();
	
	usart4_init();
	
	iic_init();

	pwm_init();
	
	dma0_1_init();
	
	eqep_init();

	adc_init();
	
	spi0_init();
		
	general_gpio_init();
	
	infrared_receive_init();

	nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
	nvic_irq_enable(ADC0_1_IRQn, 1, 1);
	nvic_irq_enable(DMA0_Channel6_IRQn, 0 ,0);
}

/*!
    \brief      main
    \param[in]  none
    \param[out] none
    \retval     none
*/

int main(void)
{
	#if 1
	nvic_vector_table_set(NVIC_VECTTAB_FLASH, NVIC_VECTAB_OFFSET);
	#endif
	
	system_init();
	
	delay_1ms(500);  // wait hardware power up
	
	flash_param_init();
	
	system_param_init();
	
	fault_param_init();	
		
	#if 1
	debug_PrintfMesg("wendatong System start ! \r\n");
	#endif

    userHdl.ctrl.FSM = FSM_STATE_IDLE;
	userHdl.assis.ledBlkPrd = LED_BLK_STATE_IDLE;	
	
	userHdl.ctrl.type_LED_left  = LED_COLOR_WHITE;
	userHdl.ctrl.type_LED_right = LED_COLOR_WHITE;
	
	key_check_init();
	
	nav_comm_frame_init();
	
	serialHMI_init(AppParamHdl.device_num);
	
	robot_interact_frame_init();
		
	while(1)
	{		
		// ========================= 1ms time base =============================
		if(systick_timestamp_1ms_flg == 1)
		{
			userHdl.assis.runflg = 1;
			systick_timestamp_1ms_flg = 0;
		}

		// ======================== periodic tasks =============================
		if(userHdl.assis.runflg == 1)
		{
			userHdl.assis.cycflg_1ms += 1;
			userHdl.assis.cycflg_1ms %= 2000;

            #if 1  // system state LED blank ctrl
            if(++counterLED[HAL_MTR_1] >= (uint16_t)(userHdl.assis.ledBlkPrd))
            {
                static uint16_t blk_cnt = 0;

                if(blk_cnt % 2 == 0)	{LED_STATE_ON();}
                else                    {LED_STATE_OFF();}

                blk_cnt++;
                counterLED[HAL_MTR_1] = 0;
            }
			
            #endif
			
			// ADC0/ADC2 convert start
			adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);
			adc_software_trigger_enable(ADC2, ADC_REGULAR_CHANNEL);	
			
			comm_frame_analysis(cmdframGroup, &userUARTRecbuf);
									
			key_status_check();
						
			AD_signal_convert();
						
            // ---------------------- 5ms task ------------------------------
            if(userHdl.assis.cycflg_1ms % 5 == 0)
			{	
				task_runtime_ms = 5;
				
				hmi_serialMini_handle();
				
				#if 0
				timer_channel_output_pulse_value_config(TIMER7, TIMER_CH_2, userHdl.ctrl.pwm_cmpa[0]);
				#endif		

				LED_color_ctrl((ENUM_LED_TYPE)userHdl.ctrl.type_LED_left, task_runtime_ms);
			}
			
			// ---------------------- 20ms 50Hz task ------------------------------
            if(userHdl.assis.cycflg_1ms % 20 == 0)
			{
				task_runtime_ms = 20;
				
				auto_charge_ctrl(task_runtime_ms);
				
				robot_paried_handle(&robot_hdl, task_runtime_ms);
				
			}

            // ---------------------- 50ms 20Hz task ------------------------------
            if(userHdl.assis.cycflg_1ms % 50 == 0)
            {
				task_runtime_ms = 50;
				
				comm_overtime_detect(task_runtime_ms);
            }

			
			gpio_output_ctrl();
			
			fault_code_update();
			
            userHdl.assis.runflg = 0;			
		}	
		
		uart_dma_sendMessg(&commUARTSendbuf);
				
		debugmsg_printf();
		
		
	}
}


/*!
    \brief      ADC0_1_IRQHandler
    \param[in]  none
    \param[out] none
    \retval     none
	\others     motor control function 
*/
void ADC0_1_IRQHandler(void)
{

    /* clear the ADC flag */
    adc_interrupt_flag_clear(ADC0, ADC_INT_FLAG_EOC);
	
    /* read ADC inserted group data register */	
	userHdl.signal.rslt.vdc_plate = ADC0_Rslt_DMA[4];	
	userHdl.signal.rslt.vdc_charge = ADC0_Rslt_DMA[5];

	userHdl.signal.rslt.level_X1 = ADC0_Rslt_DMA[6];
	userHdl.signal.rslt.level_X2 = ADC0_Rslt_DMA[7];
	
	userHdl.signal.rslt.water_X1 = ADC0_Rslt_DMA[2];
	userHdl.signal.rslt.water_X2 = ADC0_Rslt_DMA[3];
	
	userHdl.signal.rslt.temp_x1 = ADC0_Rslt_DMA[0];
	userHdl.signal.rslt.temp_x2 = ADC0_Rslt_DMA[1];
}



/*!
    \brief      
    \param[in]  none
    \param[out] none
    \retval     none
*/

void hmi_serialMini_handle(void)
{
	
	hmi_comm_handle(&printfUARTRecbuf, &printfUARTSendbuf);
	
	if(get_hmi_keyenable())
	{
		STR_HMI_KEYVALUE hmiSpeedRef;
		STR_HMI_KEYCMD   hmiCtrlCmd;
		STR_HMI_KEYREF   hmiRefcmd;
		
		
		get_hmi_keystatus(&hmiSpeedRef.data[0], HMI_KEY_VALUE);
		get_hmi_keystatus(&hmiCtrlCmd.data[0], HMI_KEY_FUN);
		get_hmi_keystatus(&hmiRefcmd.data[0], HMI_KEY_REF2);   // dust fan & edge brush & roll brush
		
		// hmi ctrl mode select
		if(hmiCtrlCmd.enable)
		{
			userHdl.ctrl.ctrlmode = 0;
			userHdl.signal.ledstatus = 0;						
		}
		else
		{
			userHdl.ctrl.ctrlmode = 0;
			userHdl.signal.ledstatus = 0;
			
			hmiSpeedRef.leftright = 0;
			hmiSpeedRef.frontback = 0;
		}
		
		#if 0
		// hmi wheel speed ctrl 
		userHdl.ctrl.speedangle_rads = ((float32_t)hmiSpeedRef.leftright) * 0.01f * 6.28f;
		userHdl.ctrl.speedline_mps   = ((float32_t)hmiSpeedRef.frontback) * 0.01f * (float32_t)0 * 0.5f;
		#endif
		
		// hmi mop motor ctrl
		userHdl.ctrl.en_leftmop = (hmiRefcmd.cmd1 == 0) ? 0 : 1;
		userHdl.ctrl.en_rightmop = (hmiRefcmd.cmd1 == 0) ? 0 : 1;
		
		// hmi other motor ctrl 
		if(hmiRefcmd.cmd2 == 0)
		{
			userHdl.ctrl.en_dustfan = 0;
			userHdl.ctrl.en_edgebrush = 0;
			userHdl.ctrl.en_mainbrush = 0;
		}
		else if(hmiRefcmd.cmd2 == 1)
		{
			userHdl.ctrl.en_dustfan = 1;
		}
		else if(hmiRefcmd.cmd2 == 2)
		{
			userHdl.ctrl.en_edgebrush = 1;						
		}
		else if(hmiRefcmd.cmd2 == 3)
		{
			userHdl.ctrl.en_mainbrush = 1;						
		}
	}
	
	if(get_hmi_faultclear())
	{
		fault_code_clear();
		
		set_hmi_faultclear(0);
	}
}




